(use-modules
 (json)
 (srfi srfi-1)  ;; union and other set operations
 (srfi srfi-9)  ;; structs
 (srfi srfi-13)  ;; hash table procedures
 (srfi srfi-9 gnu)  ;; for functional structs (not part of srfi-9 directly)
 (ice-9 hash-table))  ;; hash tables


;; ========================
;; VOCABULARY ITEM METADATA
;; ========================
(define-immutable-record-type <item-metadata>
  (make-item-metadata learned
                      description
                      relevance
                      difficulty
                      similar-words
                      mnemonics
                      explanations
                      tags
                      usage-examples
                      #;id)
  ;; predicate
  item-metadata?
  ;; getters & setters
  (learned get-item-metadata-learned
           set-item-metadata-learned)
  (description get-item-metadata-description
               set-item-metadata-description)
  (relevance get-item-metadata-relevance
             set-item-metadata-relevance)
  (difficulty get-item-metadata-difficulty
              set-item-metadata-difficulty)
  (similar-words get-item-metadata-similar-words
                 set-item-metadata-similar-words)
  (mnemonics get-item-metadata-mnemonics
             set-item-metadata-mnemonics)
  (explanations get-item-metadata-explanations
                set-item-metadata-explanations)
  (tags get-item-metadata-tags
        set-item-metadata-tags)
  (usage-examples get-item-metadata-usage-examples
                  set-item-metadata-usage-examples)
  #;(id get-item-metadata-id
      set-item-metadata-id))

(set-record-type-printer!
 <item-metadata>
 (λ (record port)
   (display
    (simple-format
     port "~a\n"
     (string-join
      '("item-metadata:"
        (string-append
         "<"
         (string-join
          (list
           #;(simple-format port "id: ~a" (item-metadata-id record))
           (simple-format port "learned: ~a" (item-metadata-learned record))
           (simple-format port "description: ~a" (item-metadata-description record))
           (simple-format port "relevance: ~a" (item-metadata-relevance record))
           (simple-format port "difficulty: ~a" (item-metadata-difficulty record))
           (simple-format port "similar-words: ~a" (item-metadata-similar-words record))
           (simple-format port "mnemonics: ~a" (item-metadata-mnemonics record))
           (simple-format port "explanations: ~a" (item-metadata-explanations record))
           (simple-format port "tags: ~a" (item-metadata-tags record))
           (simple-format port "usage-examples: ~a" (item-metadata-usage-examples record)))
          " ")
         ">")
        )
      " ")))))


(define (make-default-item-metadata vocabulary)
  (make-item-metadata #f  ;; learned
                      ""  ;; description
                      0  ;; relevance
                      0  ;; difficulty
                      #()  ;; similar_words
                      #()  ;; mnemonics
                      #()  ;; explanations
                      #()  ;; tags
                      #()))  ;; usage_examples


;; ============================
;; TRANSLATION DATA ABSTRACTION
;; ============================
(define (make-translation-data alist)
  (alist->hash-table alist))

(define (translation-data->alist translation-data)
  (hash-map->list cons m))

(define (get-translations translation-data lang)
  (hash-ref translation-data lang))

(define (set-translation! translation-data lang translation)
  (hash-set! translation-data lang translation))

(define (add-translation! translation-data lang translation)
  (define (merge-translations translation-lst translation)
    (list->vector
     (lset-union eq?
                 translation-lst
                 translation)))

  (let ([prev-translations (hash-ref translation-data lang #f)])
    (cond [prev-translations
           (hash-set! translation-data
                      lang
                      (merge-translations (vector->list prev-translations) (list translation)))]
          [else
           (hash-set! translation-data
                      lang
                      (vector translation))])))





(define-immutable-record-type <vocabulary-item>
  ;; define constructor
  (make-vocabulary-item metadata translation-data)
  ;; define predicate
  vocabulary-item?
  ;; define accessors and functional setters
  (metadata get-vocabulary-item-metadata set-vocabulary-item-metadata)
  (translation-data get-translation-data set-translation-data))


(set-record-type-printer!
 <vocabulary-item>
 (λ (record port)
   (display
    (simple-format port
                   "vocabulary-item: <~a ~a>\n"
                   (get-vocabulary-item-metadata record)
                   (get-translation-data record)))))


(define-immutable-record-type <vocabulary-metadata>
  ;; define constructor
  (make-vocabulary-metadata ...)
  ;; define predicate
  vocabulary-metadata?
  ;; define accessors and functional setters
  (identifier get-vocabulary-metadata-identifier set-vocabulary-metadata-identifier)
  (source-note get-vocabulary-metadata-source-note set-vocabulary-metadata-source-note))


(set-record-type-printer!
 <vocabulary-metadata>
 (λ (record port)
   (display
    (simple-format port
                   "vocabulary-item: <~a ~a>\n"
                   (get-vocabulary-metadata-identifier record)
                   (get-vocabulary-metadata-source-note record)))))


(define-immutable-record-type <vocabulary>
  ;; define constructor
  (make-vocabulary metadata items)
  ;; define predicate
  vocabulary?
  ;; define accessors and functional setters
  (metadata get-vocabulary-metadata set-vocabulary-metadata)
  (items get-vocabulary-items set-vocabulary-items))


(set-record-type-printer!
 <vocabulary>
 (λ (record port)
   (display
    (simple-format port
                   "vocabulary-item: <~a ~a>\n"
                   (get-vocabulary-metadata record)
                   (get-vocabulary-items record)))))
